package offer;

import java.util.Stack;

/**
 * @author ZhanBo
 * @date 2020/6/7
 */
public class Solution30 {

    public static void main(String[] args) {
        MinStack minStack = new MinStack();
        minStack.push(-2);
        minStack.push(0);
        minStack.push(-3);
        System.out.println(minStack.min());
        minStack.pop();
        System.out.println(minStack.top());
        System.out.println(minStack.min());

    }
}

/**
 * 面试题30. 包含min函数的栈
 * 定义栈的数据结构，请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中，调用 min、push 及 pop 的时间复杂度都是 O(1)。
 *
 * MinStack minStack = new MinStack();
 * minStack.push(-2);
 * minStack.push(0);
 * minStack.push(-3);
 * minStack.min();   --> 返回 -3.
 * minStack.pop();
 * minStack.top();      --> 返回 0.
 * minStack.min();   --> 返回 -2.
 */
class MinStack {
    /**
     * 存储数据
     */
    private  int [] nums;
    /**
     * 栈头索引
     */
    private  int top;
    /**
     * 最小值的索引
     */
    private  int minIndex;

    /** initialize your data structure here. */
    public MinStack() {
        nums = new int[20000];
        top = -1;
        minIndex = -1;
    }

    public void push(int x) {
        if (top== -1){
            minIndex = 0;
        }
        top++;
        nums[top] = x;
        if (x < nums[minIndex]){
            minIndex = top;
        }
    }

    public void pop() {
        if (top == minIndex){
            minIndex = 0;
            for (int i = 0 ; i < top; i++){
                if (nums[minIndex] > nums[i]){
                    minIndex = i;
                }
            }
        }
        top--;
    }

    public int top() {
        return nums[top];
    }

    public int min() {
        return nums[minIndex];
    }
}


class MinStack2 {

    Stack<Integer> A, B;

    public MinStack2() {
        A = new Stack<>();
        B = new Stack<>();
    }

    public void push(int x) {
        A.add(x);
        if(B.empty() || B.peek() >= x) {
            B.add(x);
        }
    }

    public void pop() {
        if(A.pop().equals(B.peek())) {
            B.pop();
        }
    }

    public int top() {
        return A.peek();
    }

    public int min() {
        return B.peek();
    }
}

